﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections;
using System.Windows.Data;

using System.Xml.Linq;
using System.ComponentModel;
using System.Windows.Threading;
using ObjModel = System.Collections.ObjectModel;

using PermDoc.DB;
using PermDoc.Ctrl;
using PermDoc.Ctrl.Docs;

namespace PermDoc
{

    public partial class App : Application
    {

        #region Members

        #region Visual Data
        public static InfoPanelData oInfoPanelData = new InfoPanelData();
        #endregion

        #region Thread
        public static bool _IsRefreshNightOnly = true;
        private static bool _IsShutDown = false;
        protected static bool _timer_FirstStepFinished = false;
        public enum LoadStateType { LoadData_First = 0, LoadData_LastDay = 1, LoadData_All = 2 };
        protected static LoadStateType _LoadDataType;
        protected static DispatcherTimer _timer_FirstStep = new DispatcherTimer();
        protected static DateTime? LastModify = new DateTime(2011, 1, 1, 1, 1, 1);
        protected static DateTime? BeforeCreated = DateTime.Now;
        protected static DispatcherTimer _timer_GetData = new DispatcherTimer();
        protected static DispatcherTimer _timer_idle = new DispatcherTimer();

        static Object _LockArrayRefresh_GetData = new Object();
        static object _LockDataProcess_GetData = new object();
        static object _LockIdle = new object();
        static int _iProcessGetData = 0;
        public static bool isProcessGetData
        {
            get
            {
                if (_iProcessGetData == 0)
                    return false;
                return true;
            }
        }
        static DateTime? _ProcessLastRunDateTime = null;
        static ulong _idle = 0;
        public static ulong Idle
        {
            get
            {
                return _idle;
            }
        }
#if DEBUG
        public const ulong _idleMax = 5;
#else
        public const ulong _idleMax = 30;
#endif
        #endregion

        #region Pages Ptr
        public static MainPage MainPagePtr;
        public static Welcome WelcomePagePtr;
        public static PageListCurDay PageListCurDayPtr;
        public static PageFavorites PageFavoritesPtr;
        public static PageList PageListPtr;
        #endregion

        #region Document preview Ptr
        public static Topic SelectedDocumentTopic = null;
        #endregion

        #region All Data
        public static int LoadingMonthMaxCount = 3;
        public static DateTime LoadingDateMax = DateTime.Now.AddMonths(-3);
        private static ObjModel::ObservableCollection<ShopTopic> _ShopsTopics = new ObjModel::ObservableCollection<ShopTopic>();
        public static PagedCollectionView ListView_Shops;
        private static ObjModel::ObservableCollection<CompanyTopic> _CompanyTopics = new ObjModel::ObservableCollection<CompanyTopic>();
        public static PagedCollectionView ListView_Company;
        public static ObjModel::ObservableCollection<Topic> Topics = new ObjModel::ObservableCollection<Topic>();
        public static PagedCollectionView ListView;
        #endregion

        #region CurDay
        private static DateTime? _dtCurDay;
        private static List<DocItem> _data_tmp = new List<DocItem>();
        public static ObjModel::ObservableCollection<Topic> Topics_CurDay = new ObjModel::ObservableCollection<Topic>();
        public static PagedCollectionView ListView_CurDay;
        public static PagedCollectionView ListView_Favorites;
        #endregion CurDay

        #region Viewer Document

        public static ObjModel::ObservableCollection<FilesTopic> _SelDoc_data = new ObjModel::ObservableCollection<FilesTopic>();
        public static string _SelFileName = "";

        #endregion

        #endregion

        #region Constructor
        public App()
        {
            this.Startup += this.Application_Startup;
            this.Exit += this.Application_Exit;
            this.UnhandledException += this.Application_UnhandledException;
            
            InitializeComponent();

            _LoadDataType = LoadStateType.LoadData_First;
            BeforeCreated = new DateTime(BeforeCreated.Value.Year, BeforeCreated.Value.Month, BeforeCreated.Value.Day);
            ListView_Shops = new PagedCollectionView(_ShopsTopics);
            ListView_Shops.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
            ListView_Company = new PagedCollectionView(_CompanyTopics);
            ListView_Company.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
        }
        #endregion

        #region App Methods
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            this.RootVisual = new MainPage();
            MainPagePtr = (MainPage)this.RootVisual;

            _timer_FirstStep.Tick += new EventHandler(myTimer_FirstStepTick);
            _timer_FirstStep.Interval = new TimeSpan(0, 0, 2);
            _timer_FirstStep.Start();
            _timer_GetData.Tick += new EventHandler(myTimer_GetDataTick);
#if DEBUG    
            _timer_GetData.Interval = new TimeSpan(0, 0, 10);
#else
            _timer_GetData.Interval = new TimeSpan(0, 0, 10);
#endif

            LoadingDateMax.AddMonths(-3);
            LoadingDateMax = new DateTime(LoadingDateMax.Year, LoadingDateMax.Month, 1);

            _timer_idle.Tick += new EventHandler(myTimer_Idle);
            _timer_idle.Interval = new TimeSpan(0, 0, 1);
            _timer_idle.Start();

        }
        private void Application_Exit(object sender, EventArgs e)
        {
            _IsShutDown = true;
            _timer_GetData.Stop();
            _timer_idle.Stop();
        }
        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            // If the app is running outside of the debugger then report the exception using
            // the browser's exception mechanism. On IE this will display it a yellow alert 
            // icon in the status bar and Firefox will display a script error.
            if (!System.Diagnostics.Debugger.IsAttached)
            {

                // NOTE: This will allow the application to continue running after an exception has been thrown
                // but not handled. 
                // For production applications this error handling should be replaced with something that will 
                // report the error to the website and stop the application.
                e.Handled = true;
                Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
            }
        }
        private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
        {
            try
            {
                string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
                errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");

                System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
            }
            catch (Exception)
            {
            }
        }
        #endregion

        #region Common Methods
        public static bool IsNight()
        {
            DateTime dt = DateTime.Now;
            if (dt.Hour > 6 && dt.Hour < 23)
                return false;
            return true;
        }
        public static void IdleEmpty()
        {
            lock (_LockIdle)
            {
                _idle = 0;
            }
        }
        #endregion

        #region Thread
        void myTimer_FirstStepTick(object sender, EventArgs e)
        {
            _ProcessLastRunDateTime = DateTime.Now;
            App.Invalidate(true);
        }
        void myTimer_Idle(object sender, EventArgs e)
        {
            lock (_LockIdle)
            {
                if (_idle >= ulong.MaxValue - 1)
                    _idle = App._idleMax + 1;
                _idle++;
                if (_idle > 10)
                {
                }
            }
        }
        void myTimer_GetDataTick(object sender, EventArgs e)
        {
            App.Invalidate(false);
        }
        #endregion

        #region Data
        public static Exception Invalidate(bool FirstStep)
        {
            Exception ret = null;
            if (_iProcessGetData > 0 
                && (App.Idle > (App._idleMax + 900))
                && _ProcessLastRunDateTime != null
                && (DateTime.Now - _ProcessLastRunDateTime) > (new TimeSpan(0, 0, 15, 0)) 
                )
            {
                _iProcessGetData = 0;
                return ret;
            }
            if (_IsShutDown)
                return ret;
            if (_timer_FirstStepFinished == false && _iProcessGetData > 0)
                return ret;
            if (_timer_FirstStepFinished == true && _iProcessGetData > 0)
                return ret;

            if (FirstStep == false && App.Idle <= App._idleMax)
            {
                return ret;
            }

            lock (_LockDataProcess_GetData)
            {
                _ProcessLastRunDateTime = DateTime.Now;
                string UrlStr = "";
                try
                {
                    _iProcessGetData++;
                    DateTime? dtCurDay = DateTime.Now;
                    dtCurDay = new DateTime(dtCurDay.Value.Year, dtCurDay.Value.Month, dtCurDay.Value.Day);
                    
                    if (_LoadDataType == LoadStateType.LoadData_All && App._IsRefreshNightOnly == true && App.IsNight() == false)
                        _LoadDataType = LoadStateType.LoadData_LastDay;

                    if (FirstStep)
                    {
                        _dtCurDay = dtCurDay;
                    }
                    else
                    {
                        if (_dtCurDay != dtCurDay)
                        {
                            Topics_CurDay.Clear();
                            App.oInfoPanelData.InvalidateCountCurDay = 0;
                            // Invalidate Statistic panel
                            App.oInfoPanelData.ReMakeStatistics();
                        }
                        _dtCurDay = dtCurDay;
                    }
                    if (FirstStep)
                        UrlStr = @"http://sp.korablik.local:98/ws/SP/PermDocs.aspx?Year="
                            + _dtCurDay.Value.Year + @"&Month=" + _dtCurDay.Value.Month + @"&Day=" + _dtCurDay.Value.Day
                            + "&id=" + Guid.NewGuid().ToString();
                    else
                    {
                        if (_LoadDataType == LoadStateType.LoadData_LastDay)
                        {
                            UrlStr = @"http://sp.korablik.local:98/ws/SP/PermDocs_Geq.aspx?Year="
                                + LastModify.Value.Year + @"&Month=" + LastModify.Value.Month + @"&Day=" + LastModify.Value.Day
                                + @"&Hour=" + LastModify.Value.Hour + @"&Minute=" + LastModify.Value.Minute + @"&Second=" + LastModify.Value.Second
                                + "&id=" + Guid.NewGuid().ToString();
                        }
                        else if (_LoadDataType == LoadStateType.LoadData_All)
                        {
                            if (BeforeCreated < LoadingDateMax)
                                return ret;
                            BeforeCreated -= new TimeSpan(1, 0, 0, 0);
                            UrlStr = @"http://sp.korablik.local:98/ws/SP/PermDocs.aspx?Year="
                                + BeforeCreated.Value.Year + @"&Month=" + BeforeCreated.Value.Month + @"&Day=" + BeforeCreated.Value.Day
                                + "&id=" + Guid.NewGuid().ToString();
                        }
                    }
                }
                catch (Exception err)
                {
                    ret = new Exception(err.Message, err);
                }
                if (ret == null)
                {
                    try
                    {
                        WebClient wc = new WebClient();
                        wc.DownloadStringCompleted +=
                            new DownloadStringCompletedEventHandler(Invalidate);
                        Uri myUri = new Uri(UrlStr, UriKind.Absolute);
                        wc.DownloadStringAsync(myUri);
                    }
                    catch (Exception err)
                    {
                        ret = new Exception(err.Message, err);
                    }
                }
                if (ret != null && _iProcessGetData>0)
                    _iProcessGetData = 0;
            }
            return ret;
        }
        public static void Invalidate(object sender, DownloadStringCompletedEventArgs e)
        {
            if (_iProcessGetData > 1)
            {
                _iProcessGetData--;
                return;
            }
            #region if error
            if (e.Error != null)
            {
                if (_iProcessGetData > 0)
                    _iProcessGetData = 0;
                return;
            }
            #endregion
            if (_IsShutDown)
                return;
            try
            {
                lock (_LockDataProcess_GetData)
                {
                    _iProcessGetData++;
                    #region Members
                    _data_tmp.Clear();
                    _data_tmp = null;
                    _data_tmp = new List<DocItem>();
                    #endregion
                    #region Parce
                    XDocument xDoc = XDocument.Parse(e.Result);
                    var query = from g in xDoc.Descendants("Первичные_x0020_документы")
                                select new
                                {
                                    ID = ((int?)g.Element("ID")) ?? -1,
                                    Title = (string)g.Element("Title"),
                                    State = (string)g.Element("_x005F_x0421__x005F_x043e__x005F_x0441__x005F_x0442__x005F_x043e__x005F_x044f__x005F_x043d__x005F_x0438__x005F_x0435__x005F_x0020__x005F_x0443__x005F_x0442__x005F_x0432__x005F_x0435__x005F_x0440__x005F_x0436__x005F_x0434__x005F_x0435__x005F_x043d__x005F_x0438__x005F_x044f_"),
                                    Created = (DateTime?)g.Element("Created"),
                                    Modified = (DateTime?)g.Element("Modified"),
                                    Author = (string)g.Element("Author"),
                                    Editor = (string)g.Element("Editor"),
                                    Shop = (string)g.Element("_x005F_x041c__x005F_x0430__x005F_x0433__x005F_x0430__x005F_x0437__x005F_x0438__x005F_x043d_"),
                                    Kontragent = (string)g.Element("_x005F_x041f__x005F_x043e__x005F_x0441__x005F_x0442__x005F_x0430__x005F_x0432__x005F_x0449__x005F_x0438__x005F_x043a_"),
                                    DocDate = (DateTime?)g.Element("_x005F_x0414__x005F_x0430__x005F_x0442__x005F_x0430__x005F_x0020__x005F_x043a__x005F_x043e__x005F_x043c__x005F_x043f__x005F_x043b__x005F_x0435__x005F_x043a__x005F_x0442__x005F_x0430_"),
                                    DocNum = (string)g.Element("_x005F_x041d__x005F_x043e__x005F_x043c__x005F_x0435__x005F_x0440__x005F_x0020__x005F_x043d__x005F_x0430__x005F_x043a__x005F_x043b__x005F_x0430__x005F_x0434__x005F_x043d__x005F_x043e__x005F_x0439_"),
                                };
                    foreach (var n in query)
                    {
                        DocItem o = new DocItem();
                        o.ID = n.ID;
                        o.Title = n.Title;
                        o.Created = n.Created;
                        o.Modified = n.Modified;
                        o.Author = n.Author;
                        o.Editor = n.Editor;
                        o.Shop = n.Shop;
                        o.Kontragent = n.Kontragent;
                        o.DocDate = n.DocDate;
                        o.DocNum = n.DocNum;
                        switch (n.State)
                        {
                            case "Утвержден":
                                o.State = DocState.Утвержден;
                                break;
                            case "Черновик":
                                o.State = DocState.Черновик;
                                break;
                            case "Ожидает утверждения":
                            case "Ожидают утверждения":
                                o.State = DocState.Ожидает_утверждения;
                                break;
                            default:
                                o.State = DocState.Неопределен;
                                break;
                        }
                        _data_tmp.Add(o);
                    }
                    #endregion
                    #region the end steps in method
                    if (_timer_FirstStepFinished == false)
                    {
                        _timer_FirstStep.Stop();
                        _timer_FirstStepFinished = true;
                        _timer_GetData.Start();
                    }
                    if (_LoadDataType == LoadStateType.LoadData_LastDay)
                    {
                        App.oInfoPanelData.InvalidateCountCurDay++;
                    }
                    else if (_LoadDataType == LoadStateType.LoadData_All)
                    {
                        App.oInfoPanelData.InvalidateCountTotal++;
                    }
                    RefreshDataArray();
                    #endregion
                }
            }
            catch
            {
            }
            
            if (_iProcessGetData > 0)
                _iProcessGetData = 0;
        }
        private static Exception RefreshDataArray()
        {
            Exception ret = null;
            if (_IsShutDown)
                return ret;
            lock (_LockArrayRefresh_GetData)
            {
                #region Members
                int index = -1;
                int FoundSPItemID = -1;
                string strTmp = "";
                string ShopName = "";
                string CompanyName = "";
                bool isFind = false;
                DateTime? LastModify_tmp = LastModify;
                App.oInfoPanelData.UpdateDaysConstsState();
                #endregion
                #region Is Night
                if (App.IsNight() == false && ListView!=null && App.PageListPtr != null)
                {
                    //App.ListView.GroupDescriptions.Clear();
                    //App.ListView.SortDescriptions.Clear();
                }
                #endregion
                #region foreach
                foreach (DocItem o in _data_tmp)
                {
                    #region Members
                    ShopName = "";
                    if (!String.IsNullOrEmpty(o.Shop.Name))
                        ShopName = o.Shop.Name.Trim().ToLower();
                    CompanyName = "";
                    if (!String.IsNullOrEmpty(o.Kontragent.Name))
                        CompanyName = o.Kontragent.Name.Trim().ToLower();
                    isFind = false;
                    strTmp = "";
                    #endregion
                    #region Make Data for Shops Combo
                    foreach (ShopTopic oShop in _ShopsTopics)
                    {
                        if (!String.IsNullOrEmpty(oShop.Name))
                        {
                            strTmp = oShop.Name.Trim().ToLower();
                            if (strTmp == ShopName)
                            {
                                isFind = true;
                                break;
                            }
                        }
                    }
                    if (isFind == false)
                    {
                        if (!String.IsNullOrEmpty(o.Shop.Name))
                            _ShopsTopics.Add(new ShopTopic(o.Shop));
                    }
                    #endregion
                    #region Members
                    isFind = false;
                    strTmp = "";
                    #endregion
                    #region Make Data for Company Combo
                    foreach (CompanyTopic oCompany in _CompanyTopics)
                    {
                        if (!String.IsNullOrEmpty(oCompany.Name))
                        {
                            strTmp = oCompany.Name.Trim().ToLower();
                            if (strTmp == CompanyName)
                            {
                                isFind = true;
                                break;
                            }
                        }
                    }
                    if (isFind == false)
                    {
                        if (!String.IsNullOrEmpty(o.Kontragent.Name))
                            _CompanyTopics.Add(new CompanyTopic(o.Kontragent));
                    }
                    #endregion
                    #region Parse Document items
                    if (_LoadDataType == LoadStateType.LoadData_LastDay || _LoadDataType == LoadStateType.LoadData_First)
                    {
                        if (o.Modified != null && LastModify_tmp < o.Modified)
                            LastModify_tmp = o.Modified;
                        index = FindInCurDayArray(o, ref FoundSPItemID);
                        if (index < 0)
                            DocCurDayNewItem(o);
                        else
                            DocCurDayUpdItem(o, index);
                    }
                    index = FindInGlobalArray(o, ref FoundSPItemID);
                    if (index < 0)
                        DocGlobalNewItem(o);
                    else
                        DocGlobalUpdItem(o, index);
                    #endregion
                }
                #endregion
                #region Normalize data view
                if (App.PageListCurDayPtr != null)
                {
                    DataGrid gv = App.PageListCurDayPtr.gv;
                    if (gv.Columns.Count > 0)
                    {
                        foreach (DataGridColumn c in gv.Columns)
                        {
                            if (c.Header.ToString() == "ChildTopics")
                                c.Visibility = Visibility.Collapsed;
                            //else if(c.Header.ToString() == "Created")
                            //    c.Header = "Создан";
                            //else if (c.Header.ToString() == "Modified")
                            //    c.Header = "Изменен";
                        }
                    }
                }
                #endregion
                #region the end
                App.oInfoPanelData.BeforeCreated = BeforeCreated;
                App.oInfoPanelData.InvalidateControls();
                if (_LoadDataType == LoadStateType.LoadData_First)
                {
                    LastModify = LastModify_tmp;
                    _LoadDataType = LoadStateType.LoadData_LastDay;
                }
                else if (
                    (_LoadDataType == LoadStateType.LoadData_LastDay && _IsRefreshNightOnly == true && App.IsNight() == true)
                    || (_LoadDataType == LoadStateType.LoadData_LastDay && _IsRefreshNightOnly == false)
                    )
                {
                    LastModify = LastModify_tmp;
                    _LoadDataType = LoadStateType.LoadData_All;
                }
                else if (
                    (
                    _LoadDataType == LoadStateType.LoadData_LastDay && _IsRefreshNightOnly == true && App.IsNight() == false)
                    )
                {
                    LastModify = LastModify_tmp;
                    _LoadDataType = LoadStateType.LoadData_LastDay;
                }
                else if (
                (
                _LoadDataType == LoadStateType.LoadData_All && _IsRefreshNightOnly == false)
                )
                {
                    LastModify = LastModify_tmp;
                    _LoadDataType = LoadStateType.LoadData_LastDay;
                }
                else
                {
                    LastModify = LastModify_tmp;
                    _LoadDataType = LoadStateType.LoadData_All;
                }
                if (App.PageListPtr != null && App.ListView != null && App.PageListPtr.Visibility==Visibility.Visible)
                {
                    if (App.ListView.CanSort == true)
                    {
                        //App.ListView.SortDescriptions.Clear();
                        //App.ListView.SortDescriptions.Add(new SortDescription("Дата_Док", ListSortDirection.Descending));
                    }
                }
                #endregion
            }
            return ret;
        }
        public static Exception ClearFavoritesAll()
        {
            Exception ret = null;
            if (_IsShutDown)
                return ret;
            lock (_LockArrayRefresh_GetData)
            {
                foreach (Topic o in Topics_CurDay)
                {
                    if (o.IsFavorites)
                        o.FavoritesValue = 0;
                }
            }
            return ret;
        }
        private static void DocCurDayNewItem(DocItem newitem)
        {
            if (_IsShutDown)
                return;
            Topic newtopic = new Topic(newitem);
            Topics_CurDay.Insert(0, newtopic);
        }
        private static void DocGlobalNewItem(DocItem newitem)
        {
            if (_IsShutDown)
                return;
            Topic newtopic = new Topic(newitem);
            Topics.Insert(0, newtopic);
            App.oInfoPanelData.NewItem(newitem.Created, newitem.Modified);
        }
        private static void DocCurDayUpdItem(DocItem item, int index)
        {
            if (_IsShutDown)
                return;
            if (Topics_CurDay[index].ИД == item.ID && Topics_CurDay[index].Изменён < item.Modified)
            {
                string compareText = "";
                compareText = MakeCompareText(Topics_CurDay[index], item);
                Topics_CurDay[index].Copy(item);
                Topics_CurDay[index].ImgUrl = @"http://sp.korablik.local/_layouts/IMAGES/workflows.jpg";
                Topics_CurDay[index].Tooltip = "";
                if (item.Modified.Value != null)
                {
                    Topics_CurDay[index].Tooltip += item.Modified.Value.ToString(
@"dd.MM.yy hh:mm:ss ");
                }
                Topics_CurDay[index].Tooltip +=
@"
Compare : ";
                Topics_CurDay[index].Tooltip += compareText;
            }
        }
        private static void DocGlobalUpdItem(DocItem item, int index)
        {
            if (_IsShutDown)
                return;
            if (Topics[index].ИД == item.ID && Topics[index].Изменён < item.Modified)
            {
                string compareText = "";
                compareText = MakeCompareText(Topics[index], item);
                Topics[index].Copy(item);
                Topics[index].ImgUrl = @"http://sp.korablik.local/_layouts/IMAGES/workflows.jpg";
                Topics[index].Tooltip = "";
                if (item.Modified.Value != null)
                {
                    Topics[index].Tooltip += item.Modified.Value.ToString(
@"dd.MM.yy hh:mm:ss ");
                }
                Topics[index].Tooltip +=
@"
Compare : ";
                Topics[index].Tooltip += compareText;
                App.oInfoPanelData.UpdateItem(item.Created, item.Modified);
            }
        }
        private static int FindInCurDayArray(DocItem parItem, ref int SPItemId)
        {
            int ret = -1;
            if (_IsShutDown)
                return ret;
            for(int i = Topics_CurDay.Count-1; i>=0; i--)
            {
                Topic o = Topics_CurDay[i];
                if (parItem.ID == o.ИД)
                {
                    SPItemId = o.ИД;
                    ret = i;
                    break;
                }
            }
            return ret;
        }
        private static int FindInGlobalArray(DocItem parItem, ref int SPItemId)
        {
            int ret = -1;
            if (_IsShutDown)
                return ret;
            for (int i = Topics.Count - 1; i >= 0; i--)
            {
                Topic o = Topics[i];
                if (parItem.ID == o.ИД)
                {
                    SPItemId = o.ИД;
                    ret = i;
                    break;
                }
            }
            return ret;
        }
        private static string MakeCompareText(Topic oldItem, DocItem newItem)
        {
            string ret = "";

            if (oldItem.No != newItem.Title)
            {
                ret += @"
No (старый) - " + oldItem.No + @" ; No (новый) - " + newItem.Title;
            }

            if (oldItem.N_Док != newItem.DocNum)
            {
                ret += @"
N_Док (старый) - " + oldItem.N_Док + @" ; N_Док (новый) - " + newItem.DocNum;
            }

            if (oldItem.Дата_Док != newItem.DocDate)
            {
                ret += @"
Дата_Док (старый) - ";
                if (oldItem.Дата_Док == null)
                    ret += "";
                else
                    ret += oldItem.Дата_Док.Value == null ? "" : oldItem.Дата_Док.Value.ToString("dd.MM.yyyy hh:mm:ss");
                ret += @" ; Дата_Док (новый) - ";
                ret += newItem.DocDate.Value.ToString("dd.MM.yyyy hh:mm:ss");
            }

            if (oldItem.Статус != newItem.State)
            {
                ret += @"
Статус (старый) - " + oldItem.Статус + @" ; Статус (новый) - " + newItem.State;
            }

            if (oldItem.Магазин != newItem.Shop)
            {
                ret += @"
Магазин (старый) - " + oldItem.Магазин + @" ; Магазин (новый) - " + newItem.Shop;
            }

            if (oldItem.Контрагент != newItem.Kontragent)
            {
                ret += @"
Контрагент (старый) - " + oldItem.Контрагент + @" ; Контрагент (новый) - " + newItem.Kontragent;
            }

            if (oldItem.Автор != newItem.Author)
            {
                ret += @"
Автор (старый) - " + oldItem.Автор + @" ; Автор (новый) - " + newItem.Author;
            }

            if (oldItem.Редактор != newItem.Editor)
            {
                ret += @"
Редактор (старый) - " + oldItem.Редактор + @" ; Редактор (новый) - " + newItem.Editor;
            }

            if (oldItem.Создан != newItem.Created)
            {
                ret += @"
Создан (старый) - ";
                if (oldItem.Создан == null)
                    ret += "";
                else
                    ret += oldItem.Создан.Value == null ? "" : oldItem.Создан.Value.ToString("dd.MM.yyyy hh:mm:ss");
                ret += @" ; Создан (новый) - ";
                ret += newItem.Created.Value.ToString("dd.MM.yyyy hh:mm:ss");
            }

            if (oldItem.Изменён != newItem.Modified)
            {
                ret += @"
Изменён (старый) - ";
                if (oldItem.Изменён == null)
                    ret += "";
                else
                    ret += oldItem.Изменён.Value == null ? "" : oldItem.Изменён.Value.ToString("dd.MM.yyyy hh:mm:ss");
                ret += @" ; Изменён (новый) - ";
                ret += newItem.Modified.Value.ToString("dd.MM.yyyy hh:mm:ss");
            }

            return ret;
        }
        #endregion

    }

}
